package run.bottle.securityauth.access;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.access.intercept.RequestAuthorizationContext;
import run.bottle.common.context.ThreadContext;
import run.bottle.common.entity.AppUser;
import run.bottle.urp.model.po.Permission;
import run.bottle.urp.service.PermissionService;

import java.util.List;
import java.util.function.Supplier;


/**
 * @author liyc
 * @date 2022-04-30
 */
public class AccessDecisionVoterAuthorizationManagerAdapter implements AuthorizationManager<RequestAuthorizationContext> {

    private final Logger logger = LoggerFactory.getLogger(AccessDecisionVoterAuthorizationManagerAdapter.class);

    private final PermissionService permissionService;

    public AccessDecisionVoterAuthorizationManagerAdapter(PermissionService permissionService) {
        this.permissionService = permissionService;
    }

    @Override
    public void verify(Supplier<Authentication> authentication, RequestAuthorizationContext object) {
    }

    @Override
    public AuthorizationDecision check(Supplier<Authentication> authentication, RequestAuthorizationContext context) {
        System.out.println("check");
        System.out.println(SecurityContextHolder.getContext().getAuthentication());
        String servletPath = context.getRequest().getServletPath();
        String method = context.getRequest().getMethod();
        AppUser appUser = ThreadContext.getCurrentUser();
        if (appUser != null) {
            logger.info("current username:{}", appUser.getUsername());

            List<Long> roleIds = appUser.getRoleIds();
            List<Permission> permissions = permissionService.findByRoleIds(roleIds);
            for (Permission permission : permissions) {
                logger.info("resourcePath:{}", permission.getResourcePath());
                if (servletPath.equals(permission.getResourcePath()) && method.equals(permission.getResourceMethod())) {
                    logger.info("ACCESS_GRANTED");
                    return new AuthorizationDecision(true);
                }
            }
        }
        return null;
    }
}
